package cn.uc.ucgc.community.upgrade.conf.task;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.uc.ucgc.community.upgrade.Constants;
import cn.uc.ucgc.community.upgrade.Task;
import cn.uc.ucgc.community.upgrade.Utils;
import cn.uc.ucgc.community.upgrade.conf.DeleteJob;
import cn.uc.ucgc.community.upgrade.conf.DeleteJob.DeleteItem;
import cn.uc.ucgc.community.upgrade.conf.JobType;

/**
 * 需要删除的任务
 * 
 * @author laizy@ucweb.com
 * @createDate 2014-4-1
 *
 */
public class DeleteTask extends Task {
    private static final Logger logger = LoggerFactory.getLogger(DeleteTask.class);
    //任务信息
    private List<DeleteJob> jobs;

    public DeleteTask(List<DeleteJob> jobs) {
        super.setTaskDesc("Delete File Task");
        this.jobs = jobs;
    }

    @Override
    public void doTask(StringBuilder sb) throws IOException, DocumentException {
        if (null == jobs || jobs.isEmpty()) {
            sb.append(Constants.TASK_RESULT_NOTASK_SUFFIX);
            return;
        }
        //首先将XML/prop任务分开
        List<DeleteJob> propJobs = new ArrayList<DeleteJob>();
        List<DeleteJob> xmlJobs = new ArrayList<DeleteJob>();
        for (DeleteJob job : jobs) {
            if (null == job) {
                continue;
            }
            if (JobType.PROP == job.getType()) {
                propJobs.add(job);
            } else {
                xmlJobs.add(job);
            }
        }
        
        logger.warn("Need delete prop file count:{}", propJobs.size());
        //对prop类型的做处理
        doPropJobs(propJobs);
        logger.warn("Need delete xml file count:{}", xmlJobs.size());
        //对xml类型的做处理
        doXmlJobs(xmlJobs);
    }

    private void doPropJobs(List<DeleteJob> propJobs) throws IOException {
        //读取prop配置文件，并将对应需要删除的配置删除，然后保存文件
        for (DeleteJob job : propJobs) {
            //1)获取对应待操作的文件
            File filePath = job.getSrcPath();
            logger.info("prop delete:{}", filePath.getCanonicalPath());
            List<DeleteItem> items = job.getDeleteItems();
            if (null == items || items.isEmpty()) {
                logger.warn("no delete items");
                continue;
            }
            //从原文件中读取，并收集好需要删除的key
            Properties properties = Utils.getPropValues(filePath);
            Set<String> deleteProps = new HashSet<String>();
            for (DeleteItem item : items) {
                //该配置文件，需要删除的项
                String key = item.getName();
                String originalVal = properties.getProperty(key);
                //如果目标文件中不存在，直接打印日志，走后续逻辑
                if (null == originalVal) {
                    logger.warn("no key:{}", key);
                    continue;
                }
                
                deleteProps.add(key);
            }
            //根据收集的数据，重写目标文件
            Utils.deletePropFile(filePath, deleteProps);
        }
    }

    private void doXmlJobs(List<DeleteJob> propJobs) throws IOException,
            DocumentException {
        //对xml做修改的，只能是叶子节点
        for (DeleteJob job : propJobs) {
            //1)获取对应待操作的文件
            File filePath = job.getSrcPath();
            logger.info("xml delete:{}", filePath.getCanonicalPath());
            List<DeleteItem> items = job.getDeleteItems();
            if (null == items || items.isEmpty()) {
                logger.warn("no delete items");
                continue;
            }
            //收集数据
            SAXReader srcReader = new SAXReader();
            Document srcDom = srcReader.read(filePath);
            for (DeleteItem item : items) {
                //首先要从源xml文件中获取对应的数据，这里是直接定义成dom4j的xPath格式
                String srcKeyPath = item.getName();
                Node srcVal = srcDom.selectSingleNode(srcKeyPath);
                if (null == srcVal) {
                    logger.warn("no srcKeyPath:{}", srcKeyPath);
                    continue;
                }
                
                if(!srcVal.getParent().remove(srcVal)) {
                    logger.error("remove {} Failed!", srcKeyPath);
                    continue;
                }
            }
            //保存至文件
            Utils.saveDom2Xml(srcDom, filePath);
        }
    }
}